import static java.lang.StrictMath.PI;
import model.ActionType;
import model.Game;
import model.Hockeyist;
import model.HockeyistState;
import model.Move;
import model.Unit;
import model.World;

/**
 *
 * @author Constantine Tretyak
 */
public class Defend extends AbstractStrategy {

    public Defend(Hockeyist self, World world, Game game, Move move) {
        super(self, world, game, move);
    }

    double aloneTicks = 0;

    @Override
    public void run() {

        if (getZone(getUnitWithPuck()) < 4) {
            boolean plus = true;
            for (Unit opp : getOpponents(puck)) {
                if (opp.getId() == getUnitWithPuck().getId()) {
                    continue;
                }
                if (opp.getDistanceTo(getUnitWithPuck()) > coords.getHeight() || getZone(opp) > 4.5) {
                    if (AGGRESSIVE_ATTACK_OPP_TICKS > 0) {
                        AGGRESSIVE_ATTACK_OPP_TICKS -= 3;
                    }
                    plus = false;
                    break;
                }
            }
            if (plus && AGGRESSIVE_ATTACK_OPP_TICKS < 2000) {
                AGGRESSIVE_ATTACK_OPP_TICKS++;
            }
        }

        if (self.getState() == HockeyistState.SWINGING) {   // если я остался в замахе
            move.setAction(ActionType.CANCEL_STRIKE);
            return;
        }

        if (AGGRESSIVE_ATTACK_OPP_TICKS > 0) {
            move.setTurn(self.getAngleTo(getUnitWithPuck()));
            move.setSpeedUp(1.0d);
            if (self.getDistanceTo(getUnitWithPuck()) < game.getStickLength() && moving.atSector(self, getUnitWithPuck(), game.getStickSector())) {
                move.setAction(ActionType.STRIKE);
            }
            if (oppBlockUnit(self)) {
                move.setAction(ActionType.STRIKE);
                move.setSpeedUp(1.0d);
            }
//
            if (oppFrontMeWithPuck(self) && self.getDistanceTo(puck) > game.getStickLength()) {
                move.setAction(ActionType.STRIKE);
                move.setSpeedUp(1.0d);
            }
            return;
        }

        if (puckX <= 6 && getOppsAround(getNet(false), 300).isEmpty() && aloneTicks > 0) {
            aloneTicks--;
        }

        if ((puckX <= 6 && !getOppsAround(getNet(false), 300).isEmpty()) && aloneTicks < 2000) {
            aloneTicks++;
        }

        if (getZone(puck) < getZone(getOpponents(puck).get(1)) - 1 && aloneTicks < 2000) {
            aloneTicks++;
        } else if (getZone(puck) >= getZone(getOpponents(puck).get(1)) - 1 && aloneTicks > 0) {
            aloneTicks--;
        }

        move.setAction(ActionType.TAKE_PUCK);

        if (BACK_AFTER_SHOOT_TICKS > 0 && selfX < 0.0d) {
            move.setSpeedUp(1.0d);
            move.setTurn(self.getAngleTo(getNet(true)));
            return;
        }

        if (nearTeammateWithoutCast(defendPoint).getId() == self.getId()) {   // если я ближе к точке дефа

            if (aloneTicks > 0) {   // если враг используется стратегию атаки в 1 игрока
                if (getZone(puck) < 6) {    // если шайба от 5 то 1 зоны
                    if (self.getAngleTo(puck) > 30 * PI / 180) {
                        move.setTurn(self.getAngleTo(puck));
                    } else {
                        moving.moveTo(puck, null);
                    }
                } else {
                    defendNet(false);
                }
            } else {
                defendNet(false);
            }
        } else {
            if (getZone(puck) < 6) {    // если шайба от 5 то 1 зоны
                if (aloneTicks > 0) {   // если враг используется стратегию атаки в 1 игрока
                    if (getZone(puck) < 6) {    // если шайба от 5 то 1 зоны
                        moving.moveTo(puck, null);
                    } else {
                        defendNet(true);
                    }
                } else {
                    defendNet(true);
                }
            } else {
                defendNet(true);
            }
        }

        if (getOppsAround(getNet(false), 200).size() == 1 && getZone(puck) < 5) {
            moving.moveTo(puck, null);
        }

        if (oppBlockUnit(self)) {
            move.setAction(ActionType.STRIKE);
            move.setSpeedUp(1.0d);
        }
//
        if (oppFrontMeWithPuck(self) && self.getDistanceTo(puck) > game.getStickLength()) {
            move.setAction(ActionType.STRIKE);
            move.setSpeedUp(1.0d);
        }

        if (self.getDistanceTo(puck) <= game.getStickLength() && moving.atSector(self, puck, game.getStickSector() / 2)
                && getZone(self) < 3.5d) {
            move.setAction(ActionType.STRIKE);
        }
    }
}
